#pragma once
#include <iostream>
#include <string>
#include <memory>

#define SelfDefine 1

const std::string ProtSep = " ";
const std::string LineBreakSep = "\r\n";
class Protocol
{
public:
    // 1.结构化数据的序列和反序列化
    // 2.用户区分报文边界

    // 自定义协议
    //  "len\nx op y\n"
    // len\n报文\n
    static std::string Encode(std::string &message)
    {
        std::string len = std::to_string(message.size());
        std::string package = len + LineBreakSep + message + LineBreakSep;
        return package;
    }
    // 这里无法包装package是一个完整的报文
    //  "l
    //  "len
    //  "len\n
    //  "len\n msg
    //  "len\n msg \n"
    //  "len\n msg \n""len
    //  "len\n msg \n""len\n
    // 5\r\n12345\r\n
    static bool Decode(std::string &package, std::string *message)
    {
        // 除了解包，还要判断报文的完整性, 能否正确处理具有"边界"的报文
        auto pos = package.find(LineBreakSep);
        if (pos == std::string::npos)
            return false;
        std::string lens = package.substr(0, pos); //[)
        // 报文长度（整形）
        int messagelen = std::stoi(lens);
        // 计算出处理报文的总长度：报文头长度（字符串） + 2标识符 + 报文长度
        int total = lens.size() + LineBreakSep.size() * 2 + messagelen;
        if (total > package.size())
            return false;
        // packaeg中一定有完整的一个报文
        *message = package.substr(pos + LineBreakSep.size(), messagelen);
        // 删除已经截取到的报文
        package.erase(0, total);
        return true;
    }
};
